<?php
/**
 * <class description>
 *
 * @author Matias Mirabelli <project@moyrax.com>
 *
 * @package Kingorm
 */
class Link
{
	private static $instance;
	private $hdb = array();
	private $catalog = array();

	public static $activeConnection;
	public static $activeCatalog;

	private function __construct()
	{
		// Por seguridad, no se permite más que una
		// instancia de este controlador.
		//
		if ( !empty(self::$instance) ) {
			return(null);
		}

		// Se conecta a la base de datos predeterminada.
		//
		$connection = self::addCatalog( ModelConfig::DEFAULT_CATALOG );

		if ( !$connection ) {
			$this->error(null, "No se encontró ninguna base de datos");
		}

		$this->catalog[ ModelConfig::DEFAULT_CATALOG ] = $connection;

		$connection->connect( $this );
	}

	public static function initialize()
	{
		$link = self::getInstance();

		return( self::$activeConnection );
	}

	public static function addCatalog($catalogName, $connect = false)
	{
		// Verifica que no exista la base de datos, de lo
		// contrario devuelve la referencia existente.
		//
		if ( isset(self::$instance) && self::$instance->catalogExists($catalogName) ) {
			return( self::$instance->catalog[$catalogName] );
		}

		$class = $catalogName . "Catalog";

		if ( !ClassLoader::getInstance()->loadClass( $class ) ) {
			return(null);
		}

		// Crea la clase del esquema especificado.
		//
		$catalog = ClassLoader::getInstance()->uniqueInstance($class);

		if ( $connect ) {
			$catalog->connect();
		}

		if ( !method_exists($catalog, "connect") ) {
			return(null);
		}

		self::$activeCatalog = $catalog;

		if ( self::$instance ) {
			self::$instance->catalog[$catalogName] = $catalog;
		}

		return($catalog);
	}

	/**
	 * Devuelve una instancia única de la clase. Si la
	 * instancia no existe, la crea -sólo- la primera
	 * vez que esta función sea llamada.
	 */
	public static function getInstance()
	{
		if ( isset( self::$instance ) )
			return( self::$instance );

		$link = new Link();

		self::$instance = $link;

		return( $link );
	}

	public static function getCatalog($catalogName = null)
	{
		if ( !isset($catalogName) )
			$catalogName = ModelConfig::DEFAULT_CATALOG;

		if ( !self::getInstance()->catalogExists($catalogName) )
			return(null);

		return( self::$instance->catalog[$catalogName] );
	}

	public function errorCode(CatalogBase $connection)
	{
		if ( !$this->exists($connection) )
			return(null);

		return($this->hdb->errorCode());
	}

	public function open(CatalogBase $connection)
	{
		// Si el esquema ya fue abierto, devuelve
		// la referencia anterior.
		//
		if ( $this->exists($connection) )
			return( $this->hdb[$connection->catalog] );

		// Abre una nueva conexión a la base
		// de datos especificada.
		//
		$hdb = new PDO(
			"mysql:host=". $connection->server .
			";dbname=" . $connection->catalog,
			$connection->username,
			$connection->password
		);

		$hdb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
		$hdb->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, TRUE);

		$this->hdb[ $connection->catalog ] = $hdb;

		self::$activeConnection = $hdb;

		return($hdb);
	}

	public function error(CatalogBase $source = null, $description)
	{
		if ( isset($source) && $source->name )
			echo $source->name . " -> ";

		echo $description;
	}

	private function exists(CatalogBase $connection)
	{
		if ( !isset($this->hdb[$connection->catalog]) )
			return(null);

		return(true);
	}

	private function catalogExists($catalogName)
	{
		if ( !isset($this->catalog[$catalogName]) )
			return(null);

		return(true);
	}

	private function dbSuccess(PDO $hdb)
	{
		$sCode = $hdb->errorCode();

		return(substr($sCode,0,2) == "00");
	}
}

?>
